home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
SGI Origin & Onyx2 Patches 1998 May
/
Origin and Onyx2 System Disk Patches May 1998.img
/
dist
/
patchSG0002839.idb
/
usr
/
include
/
sys
/
buf.h.z
/
buf.h
Wrap
C/C++ Source or Header
|
1998-04-01
|
13KB
|
377 lines
/**************************************************************************
* *
* Copyright (C) 1989-1993 Silicon Graphics, Inc. *
* *
* These coded instructions, statements, and computer programs contain *
* unpublished proprietary information of Silicon Graphics, Inc., and *
* are protected by Federal copyright law. They may not be disclosed *
* to third parties or copied or duplicated in any form, in whole or *
* in part, without the prior written consent of Silicon Graphics, Inc. *
* *
**************************************************************************/
/* Copyright (c) 1984 AT&T */
/* All Rights Reserved */
/* THIS IS UNPUBLISHED PROPRIETARY SOURCE CODE OF AT&T */
/* The copyright notice above does not evidence any */
/* actual or intended publication of such source code. */
#ifndef __SYS_BUF_H__
#define __SYS_BUF_H__
#ident "$Revision: 3.86 $"
#include <sys/sema.h>
#include <sys/uio.h>
struct ktrace;
/*
* Each buffer in the pool is usually doubly linked into 2 lists:
* the device with which it is currently associated (always)
* and also on a list of blocks available for allocation
* for other use (usually).
* The latter list is kept in last-used order, and the two
* lists are doubly linked to make it easy to remove
* a buffer from one list when it was found by
* looking through the other.
* A buffer is on the available list, and is liable
* to be reassigned to another disk block, if and only
* if it is not marked BUSY. When a buffer is busy, the
* available-list pointers can be used for other purposes.
* Most drivers use the forward ptr as a link in their I/O active queue.
* A buffer header contains all the information required to perform I/O.
* Most of the routines which manipulate these things are in fs_bio.c.
*/
typedef struct buf {
/*
* These first 4 fields must match the hbuf definition
* below. DO NOT CHANGE THEM OR REARRANGE THEM.
*/
sema_t b_lock; /* lock for buffer usage */
int b_flags; /* see defines below */
struct buf *b_forw; /* headed by d_tab of conf.c */
struct buf *b_back; /* " */
struct buf *av_forw; /* position on free list, */
struct buf *av_back; /* if not BUSY */
dev_t b_edev; /* major+minor device name */
int b_error; /* returned after I/O */
off_t b_offset; /* vnode offset (in basic blocks) */
unsigned b_bcount; /* transfer count */
unsigned b_resid; /* words not transferred after error */
unsigned b_remain; /* virt b_bcount for PAGEIO use only */
unsigned b_bufsize; /* size in bytes of allocated buffer */
__psunsigned_t b_sort; /* key with which to sort on queue */
union {
caddr_t b_addr; /* low order core address */
int *b_words; /* words for clearing */
struct pfdat *b_pfdat; /* pointer into b_pages list */
daddr_t *b_daddr; /* disk blocks */
} b_un;
union {
struct proc *proc; /* process doing physical or swap I/O */
struct vnode *vp; /* object associated with bp */
} b_obj;
daddr_t b_blkno; /* block # on device */
clock_t b_start; /* request start time */
struct pfdat *b_pages; /* page list for PAGEIO */
void (*b_relse)(struct buf *); /* function called by brelse */
sema_t b_iodonesema; /* lock for waiting on I/O done */
void (*b_iodone)(struct buf *); /* function called by iodone */
void *b_private; /* for driver's use */
void *b_fsprivate; /* private ptr for file systems */
void *b_fsprivate2; /* private ptr for file systems */
short b_pincount; /* count of times buf is pinned */
unsigned char b_pin_waiter; /* someone waiting for unpin? */
char b_listid; /* free list number */
char b_ref; /* # of free trips through freelist */
char b_balance; /* tree balance */
struct buf *b_dforw; /* vnode delwri chain */
struct buf *b_dback; /* vnode delwri chain */
struct buf *b_parent; /* hash parent pointer */
void *b_grio_private; /* private data for grio */
struct buf *b_grio_list; /* list of bps used in grio */
int b_flags2; /* see more defines below */
#ifdef DEBUG
struct ktrace *b_trace; /* per buffer trace buffer */
#endif
} buf_t;
typedef int opaque_t;
#define b_proc b_obj.proc
#define b_vp b_obj.vp
#define paddr(X) (paddr_t)(X->b_un.b_addr)
#define b_dmaaddr b_un.b_addr
#define b_page b_un.b_pfdat
extern buf_t *global_buf_table; /* The buffer pool itself */
extern buf_t *bfreelist; /* head of available list */
extern int bfreelistmask; /* mask for freelist nums */
struct pfree {
int b_flags;
struct buf *av_forw;
struct buf *av_back;
};
/*
* These flags are kept in b_flags.
*/
#define B_WRITE 0x00000000 /* non-read pseudo-flag */
#define B_READ 0x00000001 /* read when I/O occurs */
#define B_DONE 0x00000002 /* transaction finished */
#define B_ERROR 0x00000004 /* transaction aborted */
#define B_BUSY 0x00000008 /* not on av_forw/back list */
#define B_PHYS 0x00000010 /* Physical IO */
#define B_MAP 0x00000020 /* mappable data */
#define B_WANTED 0x00000040 /* issue wakeup when BUSY goes off */
#define B_AGE 0x00000080 /* delayed write for correct aging */
#define B_ASYNC 0x00000100 /* don't wait for I/O completion */
#define B_DELWRI 0x00000200 /* delayed write - wait until buffer needed */
#define B_OPEN 0x00000400 /* open routine called */
#define B_STALE 0x00000800
#define B_LEADER 0x00001000 /* lead buffer in a list of them */
#define B_FORMAT 0x00002000
#define B_PAGEIO 0x00004000 /* use b_pages for I/O */
#define B_MAPPED 0x00008000 /* buffer has been mapped to kernel va */
#define B_SWAP 0x00010000 /* block is on swap, paddr is physical addr */
#define B_BDFLUSH 0x00020000 /* block being written by bdflush() */
#define B_RELSE 0x00040000 /* ignore b_relse field on brelse() */
#define B_PUSH 0x00080000 /* push through free list */
#define B_PARTIAL 0x00100000 /* buffer partially done, partially undone */
#define B_UNCACHED 0x00200000 /* uncached mapping requested for memcopy */
#define B_INACTIVE 0x00400000 /* buffer header taken out of cache to */
/* reduce buffer cache memory use */
#define B_BFLUSH 0x00800000 /* delayed write buffer is being pushed out */
#define B_FOUND 0x01000000 /* bp was found in cache (for stats) */
#define B_WAIT 0x02000000 /* bp will be waited for after async push */
#define B_WAKE 0x04000000 /* wake up page-waiters on b_relse */
#define B_HOLD 0x08000000 /* tell bwrite() not to unlock buffer */
#define B_DELALLOC 0x10000000 /* backing store reserved but not allocated */
#define B_MAPUSER 0x20000000 /* buf address is user address */
#define B_DACCT 0x40000000 /* buf accounted for in dchunkxxx counters */
/*
* These flags are kept in b_flags2.
*/
#define B_GR_BUF 0x00000001 /* bp is a guaranteed rate I/O */
#define B_GR_Q 0x00000002 /* guraranteed rate I/O bp was queued */
#define B_GR_ISD 0x00000004 /* guraranteed rate I/O bp was issued */
#define B_GR_RSTRT 0x00000008 /* issue queued request */
#define B_XLV_HBUF 0x00000010 /* initial request issued to xlv */
#define B_XLVD_BUF 0x00000020 /* buffer was allocated by xlvd */
#define B_XLVD_FAILOVER \
0x00000040 /* buffer is failing over */
#define B_XLV_IOC 0x00000080 /* io context has been allocated */
#define B_XLV_ACK 0x00000100 /* buffer requires ack */
#define B_SHUFFLED 0x00000200 /* disk sched fairness already applied */
#define B_PRIO_BUF 0x00000400 /* bp is a priority I/O bp */
#define B_XFS_INO 0x00000800 /* bp contains XFS inodes */
#define B_VDBUF 0x00010000 /* buffer accounted for in vnode's v_dbuf cnt */
#define BP_IS_PRIORITY(bp) (bp->b_flags2 & B_PRIO_BUF)
#define BP_ISMAPPED(bp) ((bp->b_flags & (B_PAGEIO|B_MAPPED)) != B_PAGEIO)
/*
* Flags for incore_match() and findchunk_match().
*/
#define BUF_FSPRIV 0x1
#define BUF_FSPRIV2 0x2
#ifdef _KERNEL
#define bfree_lock(listid) \
mutex_spinlock((lock_t*)&bfreelist[(listid)].b_private)
#define bfree_unlock(listid, s) \
mutex_spinunlock((lock_t *)&bfreelist[(listid)].b_private, s)
#define nested_bfree_lock(listid) \
nested_spinlock((lock_t*)&bfreelist[(listid)].b_private)
#define nested_bfree_unlock(listid) \
nested_mutex_spinunlock((lock_t*)&bfreelist[(listid)].b_private
#ifdef DEBUG
void bfreelist_check(buf_t *);
#else
#define bfreelist_check(b)
#endif
/*
* Fast access to buffers in cache by hashing.
*/
#define bhash(d,b) ((buf_t *)&global_buf_hash[((int)(d)+(int)(b))&v.v_hmask])
typedef struct hbuf {
sema_t b_lock; /* lock for hash queue */
int b_flags;
struct buf *b_forw;
struct buf *b_back;
} hbuf_t;
extern hbuf_t *global_buf_hash;
#define BIO_MAXBSIZE_LOG2 (BPCSHIFT+8)
/* Limit for maximum offsets, in chars and BBs that can be reached via lseek */
#define BIO_MAXBSIZE (1<<BIO_MAXBSIZE_LOG2)
#define BIO_MAXBBS (1<<(BIO_MAXBSIZE_LOG2-BBSHIFT))
/*
* Hashing parameters. Each disk block is scaled into a larger block,
* whose length is twice the maximun length of a buffer block.
* Maximum overlap of buckets is thus reduced to 2.
*/
#define BIO_BBSPERBUCKETSHIFT (5)
#define BIO_BBSPERBUCKETMINUSONE ((1 << BIO_BBSPERBUCKETSHIFT) - 1)
#define BIO_BBSPERLBMINUSONE (BTOBBT(BIO_MAXBSIZE) - 1)
/*
* The bwait_pin structure is used to wait for a buffer to be unpinned.
*/
typedef struct bwait_pin {
sv_t bwp_wait; /* buffer wait variable */
int bwp_count; /* wait counter */
} bwait_pin_t;
#define NUM_BWAIT_PIN 32
#define BWAIT_PIN_MASK (NUM_BWAIT_PIN - 1)
/*
* This gets ugly in order to handle buffer allocated from the heap.
*/
#define BPTOBWP(bp) ((((bp) < &global_buf_table[0]) || \
((bp) >= &global_buf_table[v.v_buf])) ? \
&bwait_pin[0] : \
&bwait_pin[((bp) - global_buf_table) & BWAIT_PIN_MASK])
extern bwait_pin_t bwait_pin[];
/*
* Flags for get_buf() and read_buf().
*/
#define BUF_TRYLOCK 0x00000001
#define BUF_BUSY 0x00000002
/*
* Flags for incore().
*/
#define INCORE_LOCK 0x00000001
#define INCORE_TRYLOCK 0x00000002
/*
* Flags for chunk_decommission().
*/
#define CD_FLUSH 0x1
/*
* Flags for chunktoss().
*/
#define C_PUSH 0x01
#define C_EOF 0x02
/*
* Chunk tracing stuff.
*/
struct ktrace;
extern struct ktrace *buf_trace_buf;
#ifndef DEBUG
#define buftrace(id, bp)
#else /* DEBUG */
#define buftrace(id, bp) \
buftrace_enter(id, bp, (inst_t *)__return_address)
extern void buftrace_enter(char *, buf_t *, inst_t *);
#endif /* DEBUG */
enum uio_rw;
struct bmapval;
struct cred;
struct pfdat;
struct uio;
struct vnode;
struct alenlist_s;
struct iovec;
extern void binit(void);
extern buf_t *incore_match(dev_t, daddr_t, int, int, void *);
extern void notavail(buf_t *);
extern buf_t *getblk(dev_t, daddr_t, int);
extern buf_t *get_buf(dev_t, daddr_t, int, uint);
extern buf_t *geteblk(void);
extern int geterror(buf_t *);
extern buf_t *getrbuf(int);
extern buf_t *ngetrbuf(size_t);
extern buf_t *ngeteblk(size_t);
extern buf_t *bread(dev_t, daddr_t, int);
extern buf_t *breada(dev_t, daddr_t, int, daddr_t, int);
extern buf_t *read_buf(dev_t, daddr_t, int, uint);
extern void baread(dev_t, daddr_t, int);
extern int bwrite(buf_t *);
extern void bdwrite(buf_t *);
extern void bawrite(buf_t *);
extern void brelse(buf_t *);
extern void binval(dev_t);
extern void bflush(dev_t);
extern void bpin(buf_t *);
extern void bunpin(buf_t *);
extern void bwait_unpin(buf_t *);
extern int iowait(buf_t *);
extern void iodone(buf_t *);
extern int biowait(buf_t *);
extern void biodone(buf_t *);
extern void bioerror(struct buf *, int);
extern void clrbuf(buf_t *);
extern void freerbuf(buf_t *);
extern void nfreerbuf(buf_t *);
extern char *bp_mapin(buf_t *);
extern void bp_mapout(buf_t *);
extern struct pfdat *getnextpg(buf_t *, struct pfdat *);
extern caddr_t maputokv(caddr_t, size_t, int);
extern void unmaputokv(caddr_t, size_t);
extern int iomap(buf_t *);
extern int iomap_vector(buf_t *, struct iovec *, int);
extern void iounmap(buf_t *);
extern void unuseracc(void *, size_t, int);
extern void fast_unuseracc(void *, size_t, int, opaque_t *);
extern int useracc(void *, size_t, int, void *);
extern int fast_useracc(void *, size_t, int, opaque_t *);
extern int userdma(void *, size_t, int, void *);
extern int fast_userdma(void *, size_t, int, opaque_t *);
extern void undma(void *, size_t, int);
extern void fast_undma(void *, size_t, int, opaque_t *);
extern buf_t *getphysbuf(void);
extern int uiophysio(int (*)(buf_t *), buf_t *, dev_t, int, struct uio *);
extern int biophysio(int (*)(buf_t *), buf_t *, dev_t, int, daddr_t,
struct uio *);
extern void putphysbuf(buf_t *);
extern buf_t *incore(dev_t, daddr_t, int, int);
extern int biomove(buf_t *, u_int, size_t, enum uio_rw, struct uio *);
extern buf_t *chunkread(struct vnode *, struct bmapval *,
int, struct cred *);
extern buf_t *getchunk(struct vnode *, struct bmapval *, struct cred *);
extern buf_t *chunkreread(buf_t *);
extern void dchunkunchain(buf_t *);
extern void delalloc_free(buf_t *);
extern void clusterwrite(buf_t *, clock_t);
extern void bp_dcache_wbinval(buf_t *);
extern void chunktoss(struct vnode *, off_t, off_t);
extern int chunkpush(struct vnode *, off_t, off_t, int);
extern void chunkinvalfree(struct vnode *);
#ifdef TILE_DATA
extern int chunkpfind(struct pfdat *, buf_t **);
extern int chunkpreplace(buf_t *, struct pfdat *, struct pfdat *);
#endif /* TILE_DATA */
#ifdef DEBUG
extern void bflushed(dev_t);
#else
#define bflushed(dev)
#endif
#endif /* _KERNEL */
#endif /* __SYS_BUF_H__ */